﻿using System.Collections.Generic;
using System.Linq;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;

namespace Beeflys.Generator
{
    sealed class USyntaxInfo
    {
        public static void Parse(SemanticModel model, CompilationUnitSyntax root)
        {
            var syntaxInfo = new USyntaxInfo(model, root);
            syntaxInfo.Parse();
        }
        
        private USyntaxInfo(SemanticModel model, CompilationUnitSyntax root)
        {
            this.model = model;
            this.root = root;
        }

        private SemanticModel model;
        private CompilationUnitSyntax root;
        private List<string> Usings = new List<string>();
        
        private void Parse()
        {
            foreach (UsingDirectiveSyntax usingItem in root.Usings)
            {
                Usings.Add(usingItem.Name.ToFullString());
            }

            foreach (var namespaceMembers in this.root.Members)
            {
                if (namespaceMembers is NamespaceDeclarationSyntax namespaceDeclarationSyntax)
                {
                    var namespaceSymbolInfo = this.model.GetSymbolInfo(namespaceDeclarationSyntax.Name);
                    if (namespaceSymbolInfo.Symbol == null) continue;
                    var namespaceSymbol = (INamespaceSymbol) namespaceSymbolInfo.Symbol;

                    var members = namespaceSymbol.GetTypeMembers().ToList();
                    List<ISymbol> members1 = new List<ISymbol>();
                    members1.AddRange(members);
                    
                    this.ParseSource(members1, namespaceSymbol);
                }
            }

            foreach (UsingDirectiveSyntax usingItem in root.Usings)
            {
                var usingNameInfo = model.GetSymbolInfo(usingItem.Name);
                if (usingNameInfo.Symbol == null) continue;
                UNamespaceInfo.Parse((INamespaceSymbol)usingNameInfo.Symbol);
            }
        }


        private void ParseSource(List<ISymbol> members, INamespaceSymbol namespaceSymbol)
        {
            foreach (var typeMember in members)
            {
                if (typeMember is INamedTypeSymbol classSymbol)
                {
                    string fullName = classSymbol.ToString();
                    if (Mapper.Contains(fullName))
                    {
                        continue;
                    }
                    
                    var unitTypeInfo = new UTypeInfo(this.Usings, classSymbol);
                    unitTypeInfo.Parse();
                    Mapper.Add(unitTypeInfo);
                    
                    //可能会有嵌套类
                    this.ParseSource(classSymbol.GetMembers().ToList(), namespaceSymbol);
                }
            }
        }
    }
}